<template>
  <div class="xgrid" ref="xgridRef">
    <div :style="{width: rightTree? 'calc(100% - 220px)':'100%'}">
      <tiny-grid
          ref="JGridRef"
          show-header-overflow
          highlight-hover-row
          highlight-current-row
          border
          seq-serial
          stripe
          :data="list"
          :size="size"
          :show-header-overflow="false"
          footer-cell-class-name="footerCellClassName"
          :edit-config="{ trigger: trigger, mode: 'cell', showStatus: true }"
          :optimization="optimization"
          :cell-class-name="cellClass"
          :height="hei"
          :loading="load.loading"
          :show-footer="showFoot"
          :footer-method="footerMethod"
          :remote-sort="remoteSort"
          :sort-config="{ trigger: 'cell' }"
          :auto-load="false"
          @edit-closed="editClosed"
          @sort-change="sortChange"
          @cell-click="cellClick"
          @cell-dblclick="cellDblClick"
          @select-all="checkboxAll"
          @select-change="checkboxChange"
      >
        <template v-for="(item, index) in columns" :key="index">
          <tiny-grid-column
              v-if="item.title !== '操作'"
              show-overflow="tooltip"
              :type="item.type"
              :width="item.width ? item.width : 100"
              :field="item.field"
              :title="item.title"
              :headerAlign="item.headerAlign ? item.headerAlign : 'center'"
              :align="item.align ? item.align : 'center'"
              :fixed="item.fixed"
              :filter="item.filter"
              :sortable="item.sortable"
              :format-text="formatFn"
              :editor="item.editor"
          >
          </tiny-grid-column>
          <tiny-grid-column
              :align="item.align ? item.align : 'center'"
              title="操作"
              fixed="right"
              :width="item.width ? item.width : 100"
              headerAlign="center"
              v-else
          >
            <template #default="data">
              <template v-for="(btn, btnIndex) in item.btns" :key="btnIndex">
								<span class="btn" v-if="showBtn(data.row, btn)" @click="rowBtn(btn, data.row, data.rowIndex)">
									{{ btn.label }}
								</span>
              </template>
            </template>
          </tiny-grid-column>
        </template>

      </tiny-grid>
      <tiny-pager
          v-if="showPage"
          mode="complete"
          :total="total"
          v-model:page-size="pageSize"
          v-model:current-page="currentPage"
          @size-change="sizeChange"
          :page-sizes="pageSizes"
          :pageSize="50"
          @current-change="pageChange"
      ></tiny-pager>
    </div>
    <div v-if="rightTree">
      <el-scrollbar :height="gridHeight">
        <tiny-tree
            :data="treeList"
            :expand-on-click-node="false"
            :show-line="true"
            :default-expand-all="true"
            @node-click="handleNodeClick"
        ></tiny-tree>
      </el-scrollbar>
    </div>
  </div>
</template>
<script >
import tool from '@/utils/tool';
import { Grid, GridColumn, Pager, Tree,  } from '@opentiny/vue';
export default {
  name: 'JGrid',
  components: {
    TinyTree: Tree,
    TinyGrid: Grid,
    TinyGridColumn: GridColumn,
    TinyPager: Pager,
  },
  props: {
    trigger: { type: String, default: 'click' }, // 显示表格底部
    seq: { type: Boolean, default: false }, // 显示表格底部
    card: { type: Boolean, default: true }, // 显示表格底部
    showFooter: { type: Boolean, default: true }, // 显示表格底部
    showPage: { type: Boolean, default: false }, // 显示表格底部
    openPage: { type: Boolean, default: true }, // 是否打开窗口
    showCheckRow: { type: Boolean, default: true }, // 显示复选框列
    showNumRow: { type: Boolean, default: true }, // 显示行号列
    editable: { type: Boolean, default: false },
    dblClickToBill: { type: Boolean, default: false },
    rightTree: { type: Boolean, default: false },
    loading: { type: Boolean, default: false },
    autoLoad: { type: Boolean, default: true }, // 显示表格底部
    clickRowToSelect: { type: Boolean, default: false }, // 显示表格底部
    isTree: { type: Boolean, default: false }, // 树形表格
    remoteSort: { type: Boolean, default: true }, // 树形表格
    dbClickEdit: { type: Boolean, default: false }, // 双击编辑
    detail: { type: Boolean, default: false }, // 取明细表列配置
    fileName: { type: String, default: '' }, // 下载的文件名
    gridHeight: { type: [Number, String], default: 0 }, // 下载的文件名
    gridWidth: { type: Number, default: 0 }, // 下载的文件名
    offsetHeight: { type: [Number, String], default: 0 }, // 减去高度
    size: { type: String, default: 'small' }, //
    whichPage: { type: String, default: '' }, //
    header: { type: String, default: '' }, //
    listUrl: { type: String, default: '' }, //
    top: { type: Number, default: 0 }, //
    contextmenu: {
      type: Array,
      default: function () {
        return [];
      },
    }, // 表格右键菜单
    fields: {
      type: Array,
      default: function () {
        return [];
      },
    },
    dataList: {
      type: Array,
      default: function () {
        return [];
      },
    },
    searchModel: {
      type: Object,
      default: function () {
        return {};
      },
    }, // 搜索条件
  },
  data() {
    return {
      url: '',
      fieldObj: {},
      pageSize: 50,
      currentPage: 1,
      list: [],
      doevent: {
        blur () {
          console.log('blur')
        }
      },
      total: 0,
      fApi: null,
      columns: [],
      hei: this.gridHeight,
      load: {
        loading: false,
      },
      filterOpen: false,
      hideFooter: false,
      hidePage: false,
      query: {},
      filter: {
        multi: true,
        enumable: true,
        defaultFilter: true,
        inputFilter: true,
      },
      timeval: 0,
      excel: 0,
      optimization: {
        animat: false,
        delayHover: 1000,
      },
      sortArr: {}, // {}
      treeList: [],
      goodCatCode: ''
    };
  },
  emits: ['rowBtn', 'mounted', 'cellClick', 'cellDblClick', 'editClosed', 'changePage'],
  methods: {
    scrollToRow (row) {
      this.$refs.JGridRef.scrollToRow(row)
    },
    getData (index) {
      return this.$refs.JGridRef.getData(index)
    },
    getRightTreeList () {
      if(this.rightTree) {
        tool.post('dropdown/goodCatList').then(ret => {
          let list = [
            {id: 0,label:'全部', children: tool.toArrayTree(ret.data)}
          ]
          this.treeList = list
        })
      }
    },
    handleNodeClick (data) {
      this.goodCatCode = data.code?data.code:''
      this.$nextTick(() => {
        this.getList()
      })
    },
    formatFn(cell) {
      let formatter = this.colObject[cell.column.property].formatter;
      if (formatter === 'formatMoney') {
        return tool.xe.toNumber(cell.cellValue) ? tool.xe.toFixed(cell.cellValue, 2) : '';
      }
      if (formatter === 'formatQty' || formatter === 'formatZero') {
        return tool.xe.toNumber(cell.cellValue) ? tool.xe.toNumber(cell.cellValue) : '';
      }
      return cell.cellValue;
    },
    setApi(api) {
      this.fApi = api;
    },
    openEdit(pars) {
      this.$refs.JEditorRef.open({ title: pars.title, params: pars });
    },
    getList(excel = 0) {

      if (!this.url) return;
      let search = {
        goodCatCode: this.goodCatCode,
        ...this.query,
      };
      if (this.fApi) {
        if (this.fApi.getValue('search')) {
          search = Object.assign(search, this.fApi.getValue('search'));
        }
        if (this.fApi.getValue('toolbar')) {
          search = Object.assign(search, this.fApi.getValue('toolbar'));
        }
      } else {
        search = Object.assign(search, this.searchModel);
      }
      let params = {
        excel,
        whichPage: this.whichPage,
        currentPage: this.currentPage,
        pageSize: this.pageSize,
        formData: search,
        sort: this.getSort(),
      };
      this.load.loading = true;
      tool.post(this.url, params, this.load).then((ret) => {
        if (ret.stat) {
          if (excel && ret.data) {
            window.open(ret.data, '_blank');
          } else {
            this.total = ret.data.total;
            if (this.fApi) {
              if (this.fApi.getValue('toolbar')) {
                this.fApi.exec('toolbar', 'updateTotal', this.total);
              }
            }
            // ret.data.list.map((row) => {
            //   row.checked = false;
            // });
            if (ret.data.columns) {
              this.setGridColumn(ret.data.columns, true);
            }
            this.list = ret.data.list;
            this.$refs.JGridRef.loadData(ret.data.list);
            this.updateFooter();
          }
        }
      });
    },
    rowBtn(btn, row, rowIndex) {
      if (typeof btn.click === 'function') {
        btn.click(row, rowIndex);
      } else {
        this.$emit('rowBtn', btn, row);
      }
    },
    sizeChange(size) {
      this.currentPage = 1;
      this.pageChange();
    },
    pageChange() {
      this.$emit('changePage', { pageSize: this.pageSize, currentPage: this.currentPage });
    },
    setGridColumn(columns, remote = false) {
      let col = [];
      columns.map((row) => {
        row.type = row.type === 'seq' ? 'index' : row.type === 'checkbox' ? 'selection' : '';
        row.headerAlign = row.headerAlign ? row.headerAlign : 'center';
        row.align = row.align ? row.align : 'left';
        row.width = row.width ? row.width : 100;
        if (typeof row.filter === 'boolean' && row.filter) {
          row.filter = this.filter;
        } else {
          delete row.filter;
        }
        delete row.filters;
        delete row.filterRender;
        delete row.slots;
        if (row.type === 'index') {
          col.push(row);
        }
        if (row.type === 'selection') {
          row.field = 'checked';
          col.push(row);
        }
        if (row.title === '操作') {
          col.push(row);
        }
        if (row.visible) col.push(row);
      });
      //
      if (remote) {
        //
        this.$nextTick(() => {
          setTimeout(() => {
            this.$refs.JGridRef.loadColumn(col);
            this.columns = col;
          }, 20);
        });
      } else {
        this.columns = col;
      }
    },
    // 设置表格高度
    setGridHeight() {
      if (!this.gridHeight) {
        setTimeout(() => {
          let rect = this.$refs.xgridRef.getBoundingClientRect();
          let h = tool.xe.toInteger(window.innerHeight - rect.top) - 0;
          if (this.offsetHeight) {
            if (typeof this.offsetHeight === 'string') {
              h = tool.multiply(h, this.offsetHeight);
            }
            if (typeof this.offsetHeight === 'number') {
              h = h - this.offsetHeight;
            }
          }
          this.hei = h - (this.showPage ? 60 : 0);
          this.$emit('mounted');
        }, 300);
      }
    },
    // 设置列
    getGridColumns() {
      if (this.columns.length === 0) {
        tool.post('page/getGridColumns', { whichPage: this.whichPage, detail: this.detail }).then((ret) => {
          if (ret.stat) {
            this.hideFooter = ret.data.hideFooter;
            this.hidePage = ret.data.hidePage;
            if (this.detail) {
              this.columns = ret.data.detailGrid;
            } else {
              let columns = new Function('_this', '_tool', 'return' + ret.data.fields)(this, tool);
              this.setGridColumn(columns);
              if (ret.data.listUrl) {
                this.url = ret.data.listUrl ? ret.data.listUrl : 'list/bill';
                setTimeout(() => {
                  this.getList();
                }, 300);
              }
            }
          }
        });
      } else {
        if (this.listUrl) {
          this.url = this.listUrl;
          this.getList();
        }
      }
    },
    showBtn(row, btn) {
      if (typeof btn.show === 'undefined') return true;
      return new Function('row', 'return ' + btn.show)(row);
    },
    search() {
      this.currentPage = 1;
      this.getList();
    },
    // 工具栏分页
    toobarPageChange({ currentPage, pageSize }) {
      this.currentPage = currentPage;
      this.pageSize = pageSize;
      this.getList();
    },
    clearFilter() {
      this.$refs.JGridRef.clearFilter();
    },
    setActiveCell(row, field) {
      this.$refs.JGridRef.setActiveCell(row, field);
    },
    getSort() {
      if (!this.remoteSort) return;
      let list = [];
      if (!tool.xe.isEmpty(this.sortArr)) {
        for (let i in this.sortArr) {
          list.push({
            field: i,
            order: this.sortArr[i],
          });
        }
      }
      return list;
    },
    editClosed(cell) {
      this.$emit('editClosed', cell);
    },
    handlePageChange({ type, pageSize }) {
      if (type === 'size') {
        this.currentPage = 1;
      }
      this.pageSize = pageSize;
      this.getList();
    },
    refresh() {
      this.currentPage = 1;
      this.$refs.JGridRef.clearSort();
      this.$refs.JGridRef.clearFilter();
      this.sortArr = {};
      this.getList();
    },
    sortChange({ field, order }) {
      if (!this.remoteSort) return;
      if (order) {
        this.sortArr[field] = order;
      } else {
        delete this.sortArr[field];
      }
      this.getList();
    },
    checkboxChange() {
      this.updateFooter();
    },
    // 全选
    checkboxAll() {
      this.updateFooter();
    },
    rowClassName({ row }) {
      let css = '';
      if (row.billType === '小计' || row.amount === '小计') {
        css += 'row-green';
      }
      if (row.transTypeName && row.transTypeName === '小计') {
        css += ' subTotal ';
      }
      return css;
    },
    setData(total, data) {
      this.total = total;
      this.lists = data;
      this.$refs.JGridRef.loadData(data);
      this.updateFooter();
    },
    getOffset() {
      return this.$refs.xgridRef.getBoundingClientRect();
    },
    updateFooter() {
      this.$refs.JGridRef.updateFooter();
    },
    // 底部汇总
    footerMethod({ columns, data }) {
      let ret = [];
      let list = this.$refs.JGridRef.getSelectRecords();
      if (list.length === 0) list = data;
      let cols = [];
      this.columns.map((row) => {
        if (row.children) {
          row.children.map((col) => {
            cols.push(col);
          });
        } else {
          cols.push(row);
        }
      });
      ret = columns.map((column) => {
        let col = {};
        for (let i = 0; i < cols.length; i++) {
          if (cols[i].field === column.property) {
            col = cols[i];
          }
        }
        if (col.sum === true) {
          let s = tool.xe.sum(list, column.property);
          if (s) {
            if (column.formatter === 'formatMoney') {
              s = s ? tool.xe.toFixed(s, 2) : '';
            }
            return s ? tool.xe.toFixed(s, 2) : '';
          } else {
            return '';
          }
        }
        if (typeof col.sumIsLast !== 'undefined' && col.sumIsLast) {
          if (data.length - 1 >= 0) return tool.xe.toFixed(data[data.length - 1][column.property], 2);
        }

        if (typeof col.subSum !== 'undefined' && col.subSum) {
          let subList = list.filter((row) => {
            return row.transTypeName === '小计';
          });
          let s = tool.xe.sum(subList, column.property);
          if (s) {
            if (column.formatter === 'formatMoney') {
              s = s ? tool.xe.toFixed(s, 2) : '';
            }
            return s ? tool.xe.toFixed(s, 2) : '';
          } else {
            return '';
          }
        }
        return '';
      });
      return [ret];
    },
    // 返回选中行
    getSelected() {
      return this.$refs.JGridRef.getSelectRecords();
    },
    // 从列表中删除已选中的行
    removeSelecteds() {
      this.$refs.JGridRef.removeSelecteds();
    },
    // cell样式名
    cellClass({ row, column }) {
      let field = column.property;
      let css = ' ';
      if (field && field === 'billStateName') {
        if (row.billState) css += ' billState-' + row.billState;
      }
      if (field && field === 'seq') {
        css += ' seq ';
      }
      if (
          field &&
          typeof this.colObject[field] !== 'undefined' &&
          typeof this.colObject[field].canClick !== 'undefined' &&
          this.colObject[field].canClick
      ) {
        css += ' canClick ';
      }
      if (row[field] === '小计') {
        css += ' subTotal ';
      }
      if (row.transTypeName && row.transTypeName === '小计') css += ' subTotal ';
      return css;
    },
    // 双击单元格
    cellDblClick({ row, column }) {
      if (this.dbClickEdit) {
        if (this.columns && this.columns.length > 0) {
          let opCol = this.columns[this.columns.length - 1];
          if (opCol.btns && opCol.btns.length > 0) {
            for (let i = 0; i < opCol.btns.length; i++) {
              if (opCol.btns[i].label === '编辑') {
                if (typeof opCol.btns[i].click === 'function') opCol.btns[i].click(row);
                break;
              }
            }
          }
        }
      }
      // 双击行跳转到开票
      if (this.dblClickToBill) {
        if (typeof this.colObject.billNo !== 'undefined' && this.colObject.billNo.canClick) {
          tool.openPage(row, 'billNo', this.$route, this.$router);
        }
      }
      this.$emit('cellDblClick', { row, column });
    },
    // 单击单元格
    cellClick({ row, column }) {
      let field = column.property;
      let cols = this.columns.filter((row) => {
        return field === row.field;
      });
      if (this.clickRowToSelect) {
        if (!this.colObject[field].editor) {
          this.$refs.JGridRef.toggleRowSelection(row);
          this.updateFooter();
        }
      }

      if (cols.length === 1) {
        let col = cols[0];
        if (row[field] === '小计') return;

        if (row[field] && col.canClick) {
          tool.openPage(row, field, this.$route, this.$router);
        } else {
          this.$emit('cellClick', { row, column });
        }
      }
    },
    // 打印当前页面
    toPrint() {
      this.$refs.JGridRef.openPrint({ sheetName: this.fileName });
    },
    download() {
      this.$refs.JGridRef.exportCsv({
        filename: '导出文件.csv',
        original: true,
        isHeader: true,
        data: this.tableData,
      });
      // this.$refs.JGridRef.openExport();
    },
  },
  created() {
    if (this.$route.query && !tool.xe.isEmpty(this.$route.query)) {
      let que = this.$route.query;
      delete que.m;
      this.query = que;
      if (!tool.xe.isEmpty(que)) {
        // setTimeout(() => {
        //   this.fApi.exec('search', 'setData', que)
        //   // this.query = {}
        // }, 200)
      }
    }
    this.hei = this.gridHeight ? this.gridHeight : 300;
    if (this.listUrl) this.url = this.listUrl;
    if (this.fields && this.fields.length > 0) {
      this.columns = this.fields;
    }
    if (this.dataList && this.dataList.length > 0) {
      this.list = this.dataList;
    }

    if (this.whichPage) {
      this.getGridColumns();
    }
    window.addEventListener('resize', this.setGridHeight);
    this.getRightTreeList()
  },
  activated() {
    // this.getList();
    window.addEventListener('resize', this.setGridHeight);
  },
  deactivated() {
    window.removeEventListener('resize', this.setGridHeight);
  },
  computed: {
    Numeric() {
      return Numeric
    },
    showFoot() {
      return this.showFooter && !this.hideFooter;
    },
    // 显示页码
    sp() {
      return this.showPage && !this.hidePage;
    },
    layout() {
      return ['Sizes', 'PrevJump', 'PrevPage', 'Number', 'NextPage', 'NextJump', 'FullJump', 'Total'];
    },
    // 右键菜单
    tableMenu() {
      let menu = {
        header: {
          options: [
            [
              { code: 'hideColumn', name: '隐藏列', disabled: false },
              { code: 'showAllColumn', name: '取消所有隐藏列', disabled: false },
            ],
          ],
        },
        body: {
          options: [this.contextmenu],
        },
      };
      if (this.contextmenu.length === 0) return {};
      return menu;
    },
    // 选中行
    checkedRows() {
      return this.list.filter((row) => {
        return row.checked;
      });
    },
    treeConfig() {
      return this.isTree ? { children: 'children', expandAll: false } : null;
    },
    tbId() {
      return 'JGrid' + Date.now();
    },
    colObject() {
      let obj = {};
      for (let i = 0; i < this.columns.length; i++) {
        obj[this.columns[i].field] = this.columns[i];
      }
      return obj;
    },
    pageSizes() {
      return [50, 100, 500];
    },
    lists: {
      get() {
        return this.list;
      },
      set() {},
    },
  },
  watch: {
    dataList: {
      handler: function (val) {
        this.list = val;
      },
      deep: true,
    },
    fields: {
      deep: true,
      handler: function (val) {
        this.columns = val;
      },
    },
  },
  mounted() {
    this.setGridHeight();
  },
};
</script>

<style  scoped lang="scss">
:deep(.tiny-grid__body-wrapper::-webkit-scrollbar)
{
  height: 10px;
}

.xgrid {
  width: 100%;
  box-sizing: border-box;
  padding: 0 5px;
  background-color: white;
  margin-bottom: 3px;
  display: flex;
}
.btn {
  color: #01aaee;
  font-size: 12px;
  margin-right: 8px;
  user-select: none;
}
.btn {
  &:hover {
    cursor: pointer;
    color: #2b85e4;
  }
}
:deep(.subTotal) {
  font-weight: bold;
  background-color: #edfff9;
  color: #1e9fff;
  font-size: 13px;
}

:deep(.tiny-grid-cell) {
  padding: 0 4px !important;
}
:deep(.billState-draft) {
  color: mediumseagreen;
  //background-color: lightyellow;
  &.billNo {
    color: dodgerblue;
  }
}

:deep(.billState-del) {
  color: #bdbdbd;
  &.billNo {
    color: dodgerblue;
  }
}

:deep(.footerCellClassName) {
  font-size: 12px;
  height: 35px;
  padding: 0 !important;
  color: #f56c6c;
}
:deep(.canClick) {
  color: dodgerblue;
  cursor: pointer;
  &:hover {
    text-decoration: underline;
  }
}
</style>